﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EasySite.Models;

namespace EasySite.Services.Implementations
{
    public class MenuService : ServiceBase, IMenuService
    {
        #region Implementation of IMenuService

        public List<MenuItem> GetMenuItems()
        {
            var query = from menuItem in DataContext.MenuItems
                        join x in DataContext.MenuItemInRoles on menuItem.ID equals x.MenuItemID
                            into relations
                        from inRole in relations.DefaultIfEmpty()
                        where menuItem.Deleted == false
                        select new
                        {
                            menuItem.ID,
                            menuItem.DisplayText,
                            menuItem.Name,
                            menuItem.NeedAuthentication,
                            menuItem.ParentID,
                            menuItem.Sequence,
                            menuItem.Href,
                            menuItem.Controller,
                            menuItem.Action,
                            Role = inRole.Role.Name
                        };
            var items = query.ToList();
            var groupedItems = items.GroupBy(m => m.ID);
            var allMenuItems = new List<MenuItem>();
            foreach (var groupedDto in groupedItems)
            {
                var roles = groupedDto.Where(m => !string.IsNullOrEmpty(m.Role)).Select(m => m.Role);
                var defaultMenu = items.First(m => m.ID == groupedDto.Key);
                var menuItem = new MenuItem()
                                   {
                                       ID = defaultMenu.ID,
                                       DisplayText = defaultMenu.DisplayText,
                                       Name = defaultMenu.Name,
                                       NeedAuthentication = defaultMenu.NeedAuthentication,
                                       ParentID = defaultMenu.ParentID,
                                       Sequence = defaultMenu.Sequence,
                                       Href = defaultMenu.Href,
                                       Controller = defaultMenu.Controller,
                                       Action = defaultMenu.Action,
                                       Roles = roles.ToArray()
                                   };
                allMenuItems.Add(menuItem);
            }
            
            var menuItems = allMenuItems.Where(m => m.ParentID == null).OrderBy(m => m.Sequence).ToList();
            menuItems.ForEach(c => FillMenuChildren(c, allMenuItems));
            return menuItems;
        }

        #endregion

        #region private methods

        private static void FillMenuChildren(MenuItem parent, IEnumerable<MenuItem> allMenuItems)
        {
            var children = allMenuItems.Where(c => c.ParentID != null && c.ParentID == parent.ID).ToList();
            if (children.Count == 0)
            {
                return;
            }
            parent.Children.AddRange(children.OrderBy(m => m.Sequence));
            foreach (var child in children)
            {
                FillMenuChildren(child, allMenuItems);
            }
        }

        #endregion
    }
}
